/**
 * 该文件可自行根据业务逻辑进行调整
 */
import type { HttpResponse } from '@vben/request'

import { useAppConfig } from '@vben/hooks'
import { preferences } from '@vben/preferences'
import { errorMessageResponseInterceptor, RequestClient } from '@vben/request'
import { useAccessStore } from '@vben/stores'

import { message } from 'ant-design-vue'

import { AcceptLanguageOptions } from '#/config/options/locales'
import { getOptionsLabelByValue } from '#/config/options/utils'
import { useAuthStore } from '#/store'

const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD)

function createRequestClient(baseURL: string) {
    const client = new RequestClient({
        baseURL
    })

    /**
     * 重新认证逻辑
     */
    async function doReAuthenticate() {
        console.warn('Access token or refresh token is invalid or expired. ')
        const accessStore = useAccessStore()
        const authStore = useAuthStore()
        accessStore.setAccessToken(null)
        if (preferences.app.loginExpiredMode === 'modal' && accessStore.isAccessChecked) {
            accessStore.setLoginExpired(true)
        } else {
            await authStore.logout()
        }
    }

    /**
     * 刷新token逻辑
     */
    // async function doRefreshToken() {
    //   const accessStore = useAccessStore();
    //   const resp = await refreshTokenApi();
    //   const newToken = resp.data;
    //   accessStore.setAccessToken(newToken);
    //   return newToken;
    // }

    function formatToken(token: null | string) {
        return token ? `${token}` : null
    }

    // 请求头处理
    client.addRequestInterceptor({
        fulfilled: async (config) => {
            const accessStore = useAccessStore()

            config.headers.Authorization = formatToken(accessStore.accessToken)

            const locale = getOptionsLabelByValue(preferences.app.locale, AcceptLanguageOptions)
            config.headers['Accept-Language'] = locale

            return config
        }
    })

    // response数据解构
    client.addResponseInterceptor<HttpResponse>({
        fulfilled: (response) => {
            const { data: responseData, status } = response

            const { code, data } = responseData
            if (status >= 200 && status < 400 && code === 0) {
                return data
            }

            throw Object.assign({}, response, { response })
        }
    })

    // token过期的处理
    client.addResponseInterceptor(
        {
            rejected: async (error) => {
                const { response } = error

                // 如果不是 401 错误，直接抛出异常
                if (response?.status !== 401 && response?.data?.code !== 401) {
                    throw error
                }

                // 如果没有启用或者已经是重试请求了，直接跳转到重新登录
                await doReAuthenticate()
                throw error
            }
        }
        // authenticateResponseInterceptor({
        //   client,
        //   doReAuthenticate,
        //   doRefreshToken,
        //   enableRefreshToken: preferences.app.enableRefreshToken,
        //   formatToken,
        // }),
    )

    // 通用的错误处理,如果没有进入上面的错误处理逻辑，就会进入这里
    client.addResponseInterceptor(
        errorMessageResponseInterceptor((msg: string, error) => {
            // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理，根据不同的 code 做不同的提示，而不是直接使用 message.error 提示 msg
            // 当前mock接口返回的错误字段是 error 或者 message
            const responseData = error?.response?.data ?? {}
            const errorMessage = responseData?.error ?? responseData?.message ?? ''
            // 如果没有错误信息，则会根据状态码进行提示
            message.error(errorMessage || msg)
        })
    )

    return client
}

export const requestClient = createRequestClient(apiURL)

export const baseRequestClient = new RequestClient({ baseURL: apiURL })
